﻿using System.Windows;
using System.Windows.Controls;
using Dsl.Ped.Editor.Messages;
using Dsl.Ped.Framework.WPFControls.ProjectiveObject;
using GalaSoft.MvvmLight.Messaging;

namespace Dsl.Ped.Editor.Modules.ProjectiveArea
{
    /// <summary>
    /// Interaction logic for EditorView.xaml
    /// </summary>
    public partial class ProjectiveAreaView : UserControl, IProjectiveAreaView
    {
        #region Fields

        /// <summary>
        /// View model of the projective area
        /// </summary>
        private ProjectiveAreaViewModel viewModel;

        /// <summary>
        /// Active view of the editor
        /// </summary>
        private ProjectiveObjectUserControl activeProjectiveObjectUserControl;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ProjectiveAreaView"/> class.
        /// </summary>
        /// <param name="messenger">The messenger used for the communication between the editor's components</param>
        /// <param name="editorResources">Resource of the editor</param>
        public ProjectiveAreaView(Messenger messenger, EditorResources editorResources)
        {
            InitializeComponent();
            // Set the view model of the view
            ViewModel = new ProjectiveAreaViewModel(editorResources);

            projectiveObjectUserControl.ProjectiveObjectActivated += OnProjectiveObjectActivatedEvent;
            projectiveObjectUserControl.ProjectiveObjectContainerChanged += OnProjectiveObjectContainerChangedEvent;

            // Register messages
            messenger.Register<ProjectionContainerChangedMessage>(this, OnProjectionContainerChangedMessage);
        }

        #endregion

        #region Members

        /// <summary>
        /// Gets or sets the view model of this view
        /// </summary>
        public ProjectiveAreaViewModel ViewModel
        {
            get
            {
                return viewModel;
            }
            set
            {
                viewModel = value;
                DataContext = viewModel;
            }
        }

        /// <summary>
        /// Gets or sets the indication if the projective object loaded into this area has changed
        /// </summary>
        public bool IsDirty
        {
            get { return ViewModel.IsDirty; }
            set { ViewModel.IsDirty = value; }
        }

        #endregion

        /// <summary>
        /// Handler method executed when the projecitve object gets activated via an event
        /// </summary>
        /// <param name="sender">Sender of the event</param>
        /// <param name="args">Arguments of the event</param>
        private void OnProjectiveObjectActivatedEvent(object sender, RoutedEventArgs args)
        {
            var projectiveObjectArgs = (RoutedProjectiveObjectEventArgs)args;

            activeProjectiveObjectUserControl = args.OriginalSource as ProjectiveObjectUserControl;
            if (activeProjectiveObjectUserControl == null) return;
            
            ViewModel.EditorResources.ProjectionContainers = projectiveObjectArgs.ProjectionContainers;
            ViewModel.EditorResources.SelectedProjectionContainer = projectiveObjectArgs.SelectedProjectionContainer;
            
            projectiveObjectArgs.Handled = true;
        }

        /// <summary>
        /// Handler method executed when the projective object container is changed
        /// </summary>
        /// <param name="sender">Sender of the event</param>
        /// <param name="args">Arguments of the event</param>
        private void OnProjectiveObjectContainerChangedEvent(object sender, RoutedEventArgs args)
        {
            var projectiveObjectArgs = (RoutedProjectiveObjectEventArgs)args;

            activeProjectiveObjectUserControl = args.OriginalSource as ProjectiveObjectUserControl;
            if (activeProjectiveObjectUserControl == null) return;

            ViewModel.EditorResources.ProjectionContainers = projectiveObjectArgs.ProjectionContainers;
            ViewModel.EditorResources.SelectedProjectionContainer = projectiveObjectArgs.SelectedProjectionContainer;
            
            projectiveObjectArgs.Handled = true;
        }

        /// <summary>
        /// Handler method executed when the message indicating the projection container has changed is received
        /// </summary>
        /// <param name="message">Message indicating the change of the container</param>
        private void OnProjectionContainerChangedMessage(ProjectionContainerChangedMessage message) {
            if (activeProjectiveObjectUserControl == null) return;

            activeProjectiveObjectUserControl.SelectedProjectionContainer = message.NewProjectionContainer;
        }
    }
}
